package ldk.apps.adbconnections.handlers

import com.google.gson.JsonElement
import com.google.gson.JsonParser
import ldk.apps.adbconnections.MainServer
import ldk.apps.adbconnections.beans.Result
import kotlin.reflect.KParameter
import kotlin.reflect.KType
import kotlin.reflect.full.createType

/**
 * handler的基类
 * Created by ldkxingzhe@163.com on 2018/2/5.
 */
abstract class BaseHandler {

    abstract val ACTION: Short
    open val method = "action"

    fun handle(mainServer: MainServer?, action: Short, content: ByteArray?){
        val handleMethod = this::class.members.find { kCallable -> kCallable.name == method }
                ?: throw IllegalStateException("$method 方法不存在")
        try {
            val jsonParser = JsonParser()
            val paramMap = HashMap<KParameter, Any>()
            val jsonString = if (content != null) content.toString(Charsets.UTF_8) else "{}"
            val paramObj = jsonParser.parse(jsonString).asJsonObject
            handleMethod.parameters.forEach {
                if (it.kind != KParameter.Kind.INSTANCE){
                    val element = paramObj[it.name]
                    if (element == null && !it.isOptional){
                        throw IllegalArgumentException("${it.name} must not be null")
                    }else if (element != null){
                        paramMap[it] = convert(element, it.type)
                    }
                }else{
                    paramMap[it] = this
                }
            }
            val result = handleMethod.callBy(paramMap)
            when (result) {
                is Result<*> -> mainServer?.writeResponse(result)
                is ByteArray -> mainServer?.writeResponse(result)
                else -> {
                    val response = Result<Any>()
                    response.result = result
                    mainServer?.writeResponse(response)
                }
            }
        }catch (e: Exception){
            e.printStackTrace()
            val response = Result<Any>()
            response.errcode = 500
            response.errmsg = e.message
            mainServer?.writeResponse(response)
        }
    }

    fun convert(jsonElement: JsonElement, type: KType): Any{
        return when(type){
            Int::class.createType() -> jsonElement.asInt
            Float::class.createType() -> jsonElement.asFloat
            Boolean::class.createType() -> jsonElement.asBoolean
            String::class.createType() -> jsonElement.asString
            else -> throw UnsupportedOperationException("不支持该类型: $type")
        }
    }
}